package com.wulian.common.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.Base64;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;

import lombok.extern.slf4j.Slf4j;

/*
 * 利用HttpClient进行post请求的工具类
 */
@Slf4j
public class HttpClientUtil {
    //发送http的post请求,携带header的map,和body的map
    public static String postMap(String url, Map<String, String> headerMap, Map<String, String> contentMap) {
        String result = null;
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        List<NameValuePair> content = new ArrayList<NameValuePair>();
        //将content生成entity
        Iterator iterator = contentMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<String, String> elem = (Entry<String, String>) iterator.next();
            content.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
        }
        CloseableHttpResponse response = null;
        try {
            //循环增加header
            Iterator headerIterator = headerMap.entrySet().iterator();
            while (headerIterator.hasNext()) {
                Entry<String, String> elem = (Entry<String, String>) headerIterator.next();
                post.addHeader(elem.getKey(), elem.getValue());
            }
            if (content.size() > 0) {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(content, "UTF-8");
                post.setEntity(entity);
            }
            //发送请求并接收返回数据
            response = httpClient.execute(post);
            if (response != null && response.getStatusLine().getStatusCode() == 200) {
                //获取response的body部分
                HttpEntity entity = response.getEntity();
                //读取reponse的body部分并转化成字符串
                result = EntityUtils.toString(entity);
            }
            return result;
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                httpClient.close();
                if (response != null) {
                    response.close();
                }
            } catch (IOException e) {
                log.error("{}请求发生错误{}", url, e.getMessage());
            }

        }
        return null;
    }

    public static String doPost(String url, Map<String, Object> map, String charset) {
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = new SSLClient();
            int timeout = 90000;
            HttpConnectionParams.setSoTimeout(httpClient.getParams(), timeout);
            httpPost = new HttpPost(url);
            //设置参数
            List<NameValuePair> list = new ArrayList<NameValuePair>();
            Iterator iterator = map.entrySet().iterator();
            while (iterator.hasNext()) {
                Entry<String, String> elem = (Entry<String, String>) iterator.next();
                list.add(new BasicNameValuePair(elem.getKey(), elem.getValue()));
            }
            if (list.size() > 0) {
                UrlEncodedFormEntity entity = new UrlEncodedFormEntity(list, charset);
                httpPost.setEntity(entity);
            }
            HttpResponse response = httpClient.execute(httpPost);
            if (response != null) {
                HttpEntity resEntity = response.getEntity();
                if (resEntity != null) {
                    result = EntityUtils.toString(resEntity, charset);
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    /**
     * xml 请求工具类1
     *
     * @param urlStr
     * @param xmlInfo
     * @return
     */
    public static String xmldoPost(String urlStr, String xmlInfo) {
        String result = "";
        try {
            URL url = new URL(urlStr);
            URLConnection con = url.openConnection();
            con.setDoOutput(true);
            //con.setRequestProperty("Pragma:","no-cache");
            con.setRequestProperty("Cache-Control", "no-cache");
            con.setRequestProperty("Content-Type", "text/xml");
            OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
            //System.out.println("urlStr=" + urlStr);
            //System.out.println("xmlInfo=" + xmlInfo);
            //可能会加密 ，或者 传输字节流
            out.write(new String(xmlInfo.getBytes("UTF-8")));
            out.flush();
            out.close();
            BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream()));
            String line = "";
            for (line = br.readLine(); line != null; line = br.readLine()) {
                result = result + line;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    /**
     * xml 请求工具类2
     *
     * @param urlStr
     * @param soapXML
     * @return
     */
    public static String xmldoPost2(String urlStr, String soapXML) {
        OutputStream os = null;
        String result = null;
        InputStream is = null;
        InputStreamReader isr = null;
        try {
            URL url = new URL(urlStr);
            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            connection.setRequestMethod("POST");
            connection.setRequestProperty("content-type", "text/xml;charset=utf-8");
            connection.setDoInput(true);
            connection.setDoOutput(true);
            os = connection.getOutputStream();
            os.write(soapXML.getBytes());
            //String responseMessage = connection.getResponseMessage();
            int responseCode = connection.getResponseCode();
            if (responseCode == HttpStatus.SC_OK) {// 表示服务端响应成功
                is = connection.getInputStream();
                isr = new InputStreamReader(is);
                BufferedReader br = new BufferedReader(isr);
                StringBuilder sb = new StringBuilder();
                String temp = null;
                while (null != (temp = br.readLine())) {
                    sb.append(temp);
                }
                result = sb.toString();
                br.close();
            } else {
                //return "服务器未响应";
                throw new Exception("服务器响应未成功");
            }

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //System.out.println("关闭流");
            closeStream(os, is, isr);
        }
        return result;
    }

    /**
     * xml 请求工具类1
     *
     * @param urlStr
     * @param xmlInfo
     * @return
     */
    public static String clientXmldoPost(String urlStr, String xmlInfo) {
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        String result = null;
        try {
            httpClient = new SSLClient();
            httpPost = new HttpPost(urlStr);
            //设置参数
            //List<BasicNameValuePair> parameters = new ArrayList<>();
            //parameters.add(new BasicNameValuePair("xml", xmlInfo));
            //httpPost.setEntity(new UrlEncodedFormEntity(parameters,"UTF-8"));
            StringEntity stringEntity = new StringEntity(xmlInfo, "UTF-8");
            stringEntity.setContentType("application/xml");
            stringEntity.setContentEncoding("UTF-8");
            httpPost.setEntity(stringEntity);
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            return EntityUtils.toString(entity, "UTF-8");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return result;
    }

    /**
     * xml 请求工具类1
     *
     * @param urlStr
     * @return
     */
    public static String clientXmldoGet(String urlStr) {
        HttpClient httpClient = null;
        HttpGet httpGet = null;
        String result = null;
        try {
            httpClient = new SSLClient();
            httpGet = new HttpGet(urlStr);
            HttpResponse response = httpClient.execute(httpGet);
            HttpEntity entity = response.getEntity();
            result = EntityUtils.toString(entity, "UTF-8");
            return result;
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return null;
    }


    /**
     * xml 请求工具类1
     *
     * @param urlStr
     * @param xmlInfo
     * @return
     */
    public static String HKXmldoPost(String urlStr, String xmlInfo, String base64key) {
        log.info("请求数据参数为:{}", xmlInfo);
        String sign = MD5.HKsign(xmlInfo, base64key);
        log.info("请求数据签名为:{}", sign);
        log.info("请求url为:{}", urlStr + "?sign=" + sign);
        xmlInfo = new String(Base64.getEncoder().encode(xmlInfo.getBytes()));
        HttpClient httpClient = null;
        HttpPost httpPost = null;
        try {
            httpClient = new SSLClient();
            httpPost = new HttpPost(urlStr + "?sign=" + sign);
            StringEntity stringEntity = new StringEntity(xmlInfo, "UTF-8");
            stringEntity.setContentType("application/xml");
            stringEntity.setContentEncoding("UTF-8");
            httpPost.setEntity(stringEntity);
            HttpResponse response = httpClient.execute(httpPost);
            HttpEntity entity = response.getEntity();
            String responseXml = EntityUtils.toString(entity, "UTF-8");
            String responseResult = new String(java.util.Base64.getDecoder().decode(responseXml));
            log.info("请求结果解析为:{}", responseResult);
            return responseResult;
        } catch (Exception ex) {
            log.error("请求弘康接口异常:{}:", ex);
        }
        return null;
    }

    public static void closeStream(OutputStream out, InputStream is, InputStreamReader isr) {
        if (out != null) {
            //System.out.println("关闭out");
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                out = null;
            }
        }
        if (is != null) {
            //System.out.println("关闭is");
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                is = null;
            }
        }
        if (isr != null) {
            //System.out.println("关闭isr");
            try {
                isr.close();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                isr = null;
            }
        }
    }

    /**
     * @param @param  requestUrl
     * @param @param  requestMethod
     * @param @param  outputStr
     * @param @return 设定文件
     * @return String    返回类型
     * @throws
     * @Title: httpRequest
     * @Description: TODO(http请求)
     * @author 马志豪
     * @date 2019年8月7日 下午5:55:45
     * @version V1.0
     */
    public static String httpRequest(String requestUrl, String requestMethod, String outputStr) {

        // 创建SSLContext
        StringBuffer buffer = null;
        try {
            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod(requestMethod);
            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.connect();
            //往服务器端写内容
            if (null != outputStr) {
                OutputStream os = conn.getOutputStream();
                os.write(outputStr.getBytes("utf-8"));
                os.close();
            }
            // 读取服务器端返回的内容
            InputStream is = conn.getInputStream();
            InputStreamReader isr = new InputStreamReader(is, "utf-8");
            BufferedReader br = new BufferedReader(isr);
            buffer = new StringBuffer();
            String line = null;
            while ((line = br.readLine()) != null) {
                buffer.append(line);
            }
        } catch (Exception e) {
            log.error("调用保险接口异常:", e);
        }
        return buffer.toString();
    }
    /**
     * json 请求工具类2
     *
     * @param postUrl
     * @param postData
     * @return
     */
    public static String jsondoPost(String postUrl, String postData) {
        try {
            //发送POST请求
            URL url = new URL(postUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setUseCaches(false);
            conn.setDoOutput(true);
            conn.setRequestProperty("Content-Length", "" + postData.length());
            OutputStreamWriter out = new OutputStreamWriter(conn.getOutputStream(), "UTF-8");
            out.write(postData);
            out.flush();
            out.close();
            //获取响应状态
            if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
                System.out.println("connect failed!");
                return "";
            }
            //获取响应内容体
            String line, result = "";
            BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream(), "utf-8"));
            while ((line = in.readLine()) != null) {
                result += line + "\n";
            }
            in.close();
            return result;
        } catch (IOException e) {
            e.printStackTrace(System.out);
        }
        return "";

    }
    
    
    public static String hexSHA1(String value) {
		try {
			MessageDigest md = MessageDigest.getInstance("SHA-1");
			md.update(value.getBytes("utf-8"));
			byte[] digest = md.digest();
			return byteToHexString(digest);
		} catch (Exception ex) {
			throw new RuntimeException(ex);
		}
	}
	
	public static String byteToHexString(byte[] bytes) {
		return String.valueOf(org.apache.commons.codec.binary.Hex.encodeHex(bytes));
	}
	
	public static Map<String, String> headerMap(String appSecret,String appKey){
		Map<String, String> headerMap = new HashMap<String,String>();
		String nonce = String.valueOf(Math.random() * 1000000);
        String timestamp = String.valueOf(System.currentTimeMillis() / 1000);
        StringBuilder toSign = new StringBuilder(appSecret).append(nonce).append(timestamp);
        String sign = HttpClientUtil.hexSHA1(toSign.toString());
        headerMap.put("appKey", appKey);
        headerMap.put("Nonce", nonce);
        headerMap.put("Timestamp", timestamp);
        headerMap.put("Signature", sign);
        headerMap.put("Content-Type", "application/x-www-form-urlencoded");
        return headerMap;
	}
	
	public static Map<String, String> contentMap(String idCard,String userName){
		Map<String, String> contentMap = new HashMap<String,String>();
		try {
			contentMap.put("userId", URLEncoder.encode(idCard, "UTF-8"));
			contentMap.put("name", URLEncoder.encode(userName, "UTF-8"));
			contentMap.put("portraitUri", URLEncoder.encode("", "UTF-8"));
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
        return contentMap;
	}
	
	
    public static void main(String[] args) throws Exception {
    	Map<String, String> headerMap = headerMap("hxjeodbRK0d4E9", "cpj2xarlchazn");
    	Map<String, String> contentMap = contentMap("412723199405022171", "马志豪");
       
         String postMap = postMap("http://api-cn.ronghub.com/user/getToken.json", headerMap, contentMap);
   System.out.println(postMap);
	if(null != postMap && "" != postMap){
      	 Map maps = (Map)JSON.parse(postMap); 
      	 Object code = maps.get("code");
      	 if(null != code){
      		 String codeStr = code.toString();
      		 if("200".equals(codeStr)){
      			String token = maps.get("token").toString();
      			System.out.println(token);
      		 }
      	 }
       }
    }
}
